package eventos;

import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;

import javax.swing.JOptionPane;

import logica.EntidadRepetidaException;
import logica.IdExternoInexistenteException;

import controlador.ControladorEditor;

import vista.objetos.NoEsObjetoDiagramableException;
import vista.objetos.NoEsObjetoNodoException;
import vista.objetos.ObjetoGraficableRepetidoException;
import vista.paneles.hojaDibujo.CreadorDeSubdiagramas;
import vista.paneles.hojaDibujo.HojaDeDibujo;

public class EventoHojaDibujo implements MouseListener, MouseMotionListener {

	private HojaDeDibujo hoja;
	private ControladorEditor controlador;
	
	private Point punto = new Point();
	private boolean seleccion = false;
	
	public EventoHojaDibujo(HojaDeDibujo hoja, ControladorEditor controlador)
	{
		this.hoja = hoja;
		this.controlador = controlador;
	}
	
	@Override
	public void mouseDragged(MouseEvent evento) 
	{
		this.setSeleccion(true);
		this.hoja.getControladorSeleccion().seleccionar(evento.getPoint());
		this.hoja.getCanvas().repaint();
	}

	@Override
	public void mouseMoved(MouseEvent event) 
	{
		this.hoja.getPosicionMouse().setLocation(event.getX(), event.getY());
		this.hoja.getCanvas().display();		
	}

	@Override
	public void mouseClicked(MouseEvent arg0) { }

	@Override
	public void mouseEntered(MouseEvent arg0) { }

	@Override
	public void mouseExited(MouseEvent arg0) { }

	@Override
	public void mousePressed(MouseEvent event) 
	{
		if (event.isMetaDown())
		{
			this.hoja.cancelarAcciones();
			return;
		}
		
		punto.setLocation(event.getPoint());
		try
		{
			switch (this.hoja.getTipoEvento()) 
			{
				case AGREGAR_GRAFICABLE_NUEVO:
					agregarObjetoNuevo();
					break;
				case AGREGAR_GRAFICABLE_EXISTENTE:
					agregarEntidadExistente();
					break;
				default:
					break;
			}
			
		} 
		catch (EntidadRepetidaException e) 
		{
			JOptionPane.showMessageDialog(this.hoja.getCanvas(), e.getMessage(), "Entidad repetida", JOptionPane.ERROR_MESSAGE);
		}
		catch (IdExternoInexistenteException e)
		{
			JOptionPane.showMessageDialog(this.hoja.getCanvas(), e.getMessage(), "Error Inesperado Evento Hoja Dibujo", JOptionPane.ERROR_MESSAGE);
		} 
		catch (NoEsObjetoDiagramableException e)
		{
			JOptionPane.showMessageDialog(this.hoja.getCanvas(), e.getMessage(), "Error Inesperado Evento Hoja Dibujo", JOptionPane.ERROR_MESSAGE);
		} 
		catch (NoEsObjetoNodoException e)
		{
			JOptionPane.showMessageDialog(this.hoja.getCanvas(), e.getMessage(), "Error Inesperado Evento Hoja Dibujo", JOptionPane.ERROR_MESSAGE);
		} 
		catch (ObjetoGraficableRepetidoException e)
		{
			JOptionPane.showMessageDialog(this.hoja.getCanvas(), e.getMessage(), "Graficable Existente", JOptionPane.ERROR_MESSAGE);
		}
	}

	private void agregarEntidadExistente() throws NoEsObjetoNodoException, ObjetoGraficableRepetidoException, NoEsObjetoDiagramableException 
	{
		if (this.hoja.getGraficableFlotante() != null)
		{
			this.controlador.agregarObjetoExistenteAlModelo(this.hoja.getGraficableFlotante());
			this.hoja.agregarGraficableFijo();
			this.hoja.getCanvas().repaint();
		}
		
	}

	private void agregarObjetoNuevo() throws EntidadRepetidaException, IdExternoInexistenteException, NoEsObjetoDiagramableException, NoEsObjetoNodoException, ObjetoGraficableRepetidoException 
	{
		if (this.hoja.getGraficableFlotante() != null)
		{
			this.controlador.agregarObjetoAlModelo(this.hoja.getGraficableFlotante());
			this.hoja.agregarGraficableFijo();
			this.hoja.getCanvas().repaint();
		}
	}

	@Override
	public void mouseReleased(MouseEvent mouse)
	{
		if(!this.getSelecciona())
			return;
		
		if (mouse.isMetaDown())
			this.hoja.getControladorSeleccion().cancelarSeleccion();
		else
		{
			this.hoja.getControladorSeleccion().seleccionar(mouse.getPoint());
			
			if (this.hoja.getControladorSeleccion().hayUnObjetoSeleccionado())
				CreadorDeSubdiagramas.pedirNombreSubdiagrama();
				
		}
		
		this.setSeleccion(false);
		this.hoja.getControladorSeleccion().cancelarSeleccion();
		this.hoja.getCanvas().repaint();
	}
	
	
	private synchronized boolean getSelecciona(){
		return this.seleccion;
	}

	private synchronized void setSeleccion(boolean seleccion){
		this.seleccion = seleccion;
	}
}
